package com.misoneism.fire.service
{
	import com.google.maps.LatLng;
	import com.misoneism.fire.event.IncidentParserEvent;
	import com.misoneism.fire.model.IIncident;
	import com.misoneism.fire.model.IncidentTypeEnum;
	import com.misoneism.fire.model.MFBIncident;
	
	import org.as3commons.collections.framework.IIterator;
	import org.as3commons.collections.framework.IList;
	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNotNull;
	import org.flexunit.async.Async;

	public class MFBIncidentParserTest
	{
		private static const GOOD_DATA: XML =
			<markers updated="Mon Jul 18 17:16:24 EST 2011">
				<marker id="110704870" lat="-37.84158547610766" lng="144.99519411865563"
						address="SOUTH YARRA, 522 CHAPEL ST / PALERMO ST + BOND ST" status_code="5" status_desc="UNDER CONTROL"
						type_code="1" type_desc="STRUCTURE FIRE" appliences="[P35B, P35A, LP35, FGD08]"/>
			
				<marker id="110704871" lat="-37.839693450629305" lng="144.99714835464013"
						address="SOUTH YARRA, / TOORAK RD + RIVER ST" status_code="2" status_desc="INVESTIGATING"
						type_code="1" type_desc="STRUCTURE FIRE" appliences="[TB10, P38A, P10, FGD10]"/>
			
				<marker id="110704899" lat="-37.67103529156874" lng="144.96819170439107"
						address="CAMPBELLFIELD, 13 ARI DR / MALCOLM PL + SARAH ST" status_code="3" status_desc="NOT YET UNDER CONTROL"
						type_code="1" type_desc="STRUCTURE FIRE" appliences="[WT5, WGLE, TB7, T44, R7, PT7, PT52, PT5, FGD10, BS38, AOC13]"/>
			
				<marker id="110704912" lat="-37.895796857718224" lng="145.01453033073162"
						address="CAULFIELD SOUTH, 18 VENUS ST / SATURN ST + JUPITER ST" status_code="5" status_desc="UNDER CONTROL"
						type_code="17" type_desc="MEDICAL EMERGENCY" appliences="[P32, FGD13]"/>
			
				<marker id="110704937" lat="-37.88173437064013" lng="144.76321542097097"
						address="SEABROOK, 4 BELEURA WAY / SEABROOK BLVD + THE TERRACE -" status_code="1" status_desc="INITIATED"
						type_code="1" type_desc="STRUCTURE FIRE" appliences="[PTCOP1, PT40, P46, FGD14, CPTCO]"/>
			
				<marker id="110705047" lat="-37.85841844347994" lng="144.80969907658923"
						address="ALTONA, 193 MAIDSTONE ST / SLOUGH RD + MORROW ST" status_code="5" status_desc="UNDER CONTROL"
						type_code="4" type_desc="INCIDENT" appliences="[P46, FGD14]"/>

				<marker id="110705049" lat="-37.72894963135516" lng="145.00414074131183"
						address="RESERVOIR, 11 TRUDGEON AV / STATION ST + HENRY ST" status_code="5" status_desc="UNDER CONTROL"
						type_code="1" type_desc="STRUCTURE FIRE" appliences="[TB7, P14, P12, FGD12]"/>
			</markers>;
		
		private static const GOOD_DATA_DATE: Number = 1310973384000;
		
		private var _mfbIncidentParser: MFBIncidentParser;
		
		[Before]
		public function setUp(  ): void
		{
			_mfbIncidentParser = new MFBIncidentParser(  );
		}
		
		
		[Test(async)]
		public function testCorrectlyParsesData(  ): void
		{
			_mfbIncidentParser.addEventListener( IncidentParserEvent.COMPLETED,
				Async.asyncHandler( this, testCorrectlyParsesDataProcessed, 1000 ) );
			
			_mfbIncidentParser.parseXML( GOOD_DATA );
		}
		
		private function testCorrectlyParsesDataProcessed( event: IncidentParserEvent, ... args ): void
		{
			var incidents: IList = event.incidents;
			
			var incident: IIncident = getIncidentById( incidents, 110704870 );
			assertNotNull( incident );
			
			assertEquals( -37.84158547610766, incident.location.lat(  ) );
			assertEquals( 144.99519411865563, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.STRUCTURE, incident.type );
			assertEquals( 4, incident.appliances );
			
			
			incident = getIncidentById( incidents, 110704871 );
			assertNotNull( incident );
			
			assertEquals( -37.839693450629305, incident.location.lat(  ) );
			assertEquals( 144.99714835464013, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.STRUCTURE, incident.type );
			assertEquals( 4, incident.appliances );
			
			
			incident = getIncidentById( incidents, 110704899 );
			assertNotNull( incident );
			
			assertEquals( -37.67103529156874, incident.location.lat(  ) );
			assertEquals( 144.96819170439107, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.STRUCTURE, incident.type );
			assertEquals( 11, incident.appliances );
			
			
			incident = getIncidentById( incidents, 110704912 );
			assertNotNull( incident );
			
			assertEquals( -37.895796857718224, incident.location.lat(  ) );
			assertEquals( 145.01453033073162, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.MEDICAL_EMERGENCY, incident.type );
			assertEquals( 2, incident.appliances );
			
			
			incident = getIncidentById( incidents, 110705047 );
			assertNotNull( incident );
			
			assertEquals( -37.85841844347994, incident.location.lat(  ) );
			assertEquals( 144.80969907658923, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.INCIDENT, incident.type );
			assertEquals( 2, incident.appliances );
			
			
			incident = getIncidentById( incidents, 110705049 );
			assertNotNull( incident );
			
			assertEquals( -37.72894963135516, incident.location.lat(  ) );
			assertEquals( 145.00414074131183, incident.location.lng(  ) );
			assertEquals( GOOD_DATA_DATE, incident.whenCreated.time );
			assertEquals( GOOD_DATA_DATE, incident.whenUpdated.time );
			assertEquals( IncidentTypeEnum.STRUCTURE, incident.type );
			assertEquals( 4, incident.appliances );
		}
		
		
		/**
		 * Get an incident matching the specified ID.
		 */
		private function getIncidentById( incidents: IList, id: uint ): IIncident
		{
			var incidentsIterator: IIterator = incidents.iterator(  );
			
			while ( incidentsIterator.hasNext(  ) )
			{
				var incident: MFBIncident = incidentsIterator.next(  );
				
				if ( incident.id == id )
				{
					return incident;
				}
			}
			
			return null;
		}
	}
}